#pragma once
#include <string>
#include <functional>
#include <memory>
#include <unistd.h>
class Connection;
class TcpServer;

using ConnectionPtr = std::shared_ptr<Connection>;
using func_t = std::function<void(ConnectionPtr)>;

class Connection
{
public:
    Connection(int sockfd, int event, TcpServer *R)
        : _sockfd(sockfd), _event(event), _R(R) {}

    ~Connection() {}

    void RegisterCallback(func_t recver,
                          func_t sender,
                          func_t excepter)
    {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }

    int GetSockfd()
    {
        return _sockfd;
    }

    uint32_t GetEvent()
    {
        return _event;
    }

    void AddInbuffer(const char *buffer)
    {
        _inbuffer += buffer;
    }

    void AddOutbuffer(const char *buffer)
    {
        _outbuffer += buffer;
    }

    std::string &inbuffer()
    {
        return _inbuffer;
    }

    std::string &outbuffer()
    {
        return _outbuffer;
    }

    bool OutBufferEmpty()
    {
        return _outbuffer.empty();
    }

    void SetEvent(uint32_t event)
    {
        _event = event;
    }
    void Close()
    {
        ::close(_sockfd);
    }

private:
    int _sockfd;
    uint32_t _event;
    std::string _inbuffer;
    std::string _outbuffer;

public:
    // 处理业务的方法
    func_t _recver;
    func_t _sender;
    func_t _excepter;

    TcpServer *_R; // 回指指针
};

class ConnectionFactory
{
public:
    static ConnectionPtr BuildListenConn(int listensock, uint32_t event, func_t recver, TcpServer *R)
    {
        // 1.创建conn
        ConnectionPtr conn = std::make_shared<Connection>(listensock, event, R);
        // 注册回调函数
        conn->RegisterCallback(recver, nullptr, nullptr);
        return conn;
    }

    static ConnectionPtr BuildNormalConnn(int sock, uint32_t event, func_t recver,
                                          func_t sender, func_t excepter, TcpServer *R)
    {
        ConnectionPtr conn = std::make_shared<Connection>(sock, event, R);
        conn->RegisterCallback(recver, sender, excepter);
        return conn;
    }
};